<template>
  <div class="tms-ag-grid" v-loading="loading">
    <!-- table表格 -->
    <ag-grid-vue :style="{ width: '100%', height }" :class="{ 'ag-theme-balham': true, 'tms-highlight-current-row': highlightCurrentRow }" ref="agGridVue" v-bind="$attrs"
      :animateRows="true" :gridOptions="gridOptions" :localeText="localeText" :columnDefs="columns" :rowData="tableData" :rowSelection="rowSelection" :suppressRowClickSelection="hasCheck"
      :rowHeight="30" :headerHeight="tmsShowFilter ? 30 : 45" :floatingFiltersHeight="tmsShowFilter ? 45 : 0" :singleClickEdit="true" @selection-changed="selectionChange" @cell-clicked="onCellClicked"
      @filter-changed="filterChangeHandler" @grid-ready="onGridReady">
    </ag-grid-vue>
    <div v-if="searchBox == true" class="search_btn" :style="{ left: !hasCheck||!hasEdit ? '4px' : '54px' }">
      <i @click="getTableData" class="el-icon-search"></i>
      <i @click="delSearchData($event)" class="el-icon-delete"></i>
    </div>
    <!-- 分页 -->
    <div v-if="pageDetail" class="pagination-container page">
      <el-pagination layout="total, prev, pager, next" background @current-change="handleCurrentChange" :current-page="page"
        :page-size="pageSize" :total="total">
      </el-pagination>
    </div>
  </div>
</template>
<script>
import { AgGridVue } from 'ag-grid-vue'
import TableFilter from './AgGrid/TableFilter.vue'
import bus from '@/bus/bus'

export default {
  name: 'Table',
  props: {
    //表格数据传入
    tableData: {
      type: Array,
      default: () => []
    },
    //传入表格列
    tableConfig: {
      type: Array,
      default: function() {
        return []
      }
    },
    //当前行是否高亮
    highlightCurrentRow: {
      type: Boolean,
      default: false
    },
    //是否显示复选框
    hasCheck: {
      type: Boolean,
      default: false
    },
    //是否显示编辑图标
    hasEdit: {
      type: Boolean,
      default: false
    },
    //是否显示删除条件查询和条件查询按钮
    searchBox: {
      type: Boolean,
      default: true
    },
    //是否在表尾显示合计行
    showSummary: {
      type: Boolean,
      default: false
    },
    //是否显示筛选行
    tmsShowFilter: {
      type: Boolean,
      default: true
    },
    //高度
    height: {
      type: String,
      default: '680px'
    },
    //是否分页
    pageDetail: {
      type: Boolean,
      default: true
    },
    pagination: {
      type: Boolean,
      default: true
    },
    //表格数据总条数
    total: {
      type: Number,
      default: 0
    },
    //当前页数
    page: {
      type: Number,
      default: 1
    },
    //每页显示几条数据
    pageSize: {
      type: Number,
      default: 20
    },
    pageSizes: {
      type: Array,
      default: function() {
        return this.PAGESIZES
      }
    }
  },
  data() {
    return {
      filterParams: {},
      loading: false,
      tableLoading: false,
      gridObj: null,
      gridOptions: {
        getRowClass: this.rowClass,
        enableCellTextSelection: true,
        defaultColDef: {
          lockPosition: true
        }
      },
      localeText: {
        noRowsToShow: this.$t('other.none')
      },
      hasIndex: true,
      rowSelection: 'multiple',
      columns: [], //表格最终显示的列
      rowData: [],
      listConfig: {},
      options: {}
    }
  },
  computed: {
    pinnedWidth() {
      const { hasCheck, hasIndex, hasEdit } = this
      let width = 30
      if (hasCheck && !hasEdit) {
        width = 60
      }
      if (!hasCheck && !hasEdit) {
        width = 60
      }
      return width
    }
  },
  components: {
    AgGridVue,
    TableFilter
  },
  beforeMount() {
    this.initSetting()
    this.gridOptions.context = {
      componentParent: this
    }
  },
  methods: {
    getTableData() {
      const { page, pageSize } = this
      const filterParams = this._.cloneDeep(this.filterParams)
      this.$emit('findData', page, filterParams)
    },
    summaryInit(totalData) {
      const summaryData = [
        { index: this.$t('model.total'), summary: true, ...totalData }
      ]
      this.gridObj.api.setPinnedBottomRowData(summaryData)
    },
    //初始化设置
    initSetting() {
      this.columns = []
      if (this.tableConfig && this.tableConfig.length > 0) {
        this.columns = this.tableConfig.map(obj => this.elTableToAgGrid(obj))
        this.afterInitColumn()
        this.showColumns = this.columns
        this.allColumns = this.columns
        this.showExportColumns = this.columns
      }
    },
    afterInitColumn() {
      if (this.immediate) {
        this.getTableData()
      }
      const columns = this._.cloneDeep(this.columns)
      let pl_width = 0
      columns[0].pinned = 'left'
      columns[0].maxWidth = columns[0].width
      pl_width += columns[0].width
      this.columns = columns
      let prependColumns = []
      if (this.hasIndex) {
        //序号列
        let _self = this
        let indexCloumn = {
          headerName: this.$t('app.index'),
          field: 'index',
          maxWidth: 46,
          minWidth: 46,
          width: 46,
          pinned: 'left',
          cellStyle: { 'text-align': 'center' },
          cellRenderer: _self.indexFormat,
          headerClass: 'tms-no-children-header'
        }
        pl_width += 46
        prependColumns.push(indexCloumn)
      }
      if (this.hasCheck) {
        //选择列
        let checkCloumn = {
          headerName: '',
          field: 'selection',
          checkboxSelection: true,
          headerCheckboxSelection: true,
          headerCheckboxSelectionFilteredOnly: true,
          maxWidth: this.pinnedWidth,
          minWidth: this.pinnedWidth,
          width: this.pinnedWidth,
          pinned: 'left',
          cellClass: 'tms-cell-index-select',
          headerClass: 'tms-no-children-header'
        }
        pl_width += this.pinnedWidth
        prependColumns.push(checkCloumn)
      }
      if (this.hasEdit) {
        //编辑列
        let checkCloumn = {
          headerName: '',
          field: 'edit',
          maxWidth: this.pinnedWidth,
          minWidth: this.pinnedWidth,
          width: this.pinnedWidth,
          pinned: 'left',
          cellClass: params => {
            if (params.data.summary) {
              return
            } else {
              return 'el-icon-edit'
            }
          },
          headerClass: 'tms-no-children-header'
        }
        pl_width += this.pinnedWidth
        prependColumns.push(checkCloumn)
      }
      this.columns = prependColumns.concat(this.columns)
      this.$nextTick(() => {
        const scrollDom = this.$refs.agGridVue.$el.querySelector(
          '.ag-body-horizontal-scroll-viewport'
        )
        scrollDom.style.paddingLeft = pl_width + 'px'
      })
    },
    /**
     * el-table列配置项转换为ag-grid列配置项
     * 参数：elColumn：el-table的列配置
     * 返回：ag-grid的列配置
     */
    elTableToAgGrid(elColumn) {
      let agColumn = this._.cloneDeep(elColumn)
      agColumn.resizable = false
      // agColumn.sortable = this.sortable;
      agColumn.floatingFilter = this.tmsShowFilter
      agColumn.headerName =
        this.$t(elColumn.name) || this.$t(elColumn.label) || ''
      agColumn.field = elColumn.code || elColumn.prop
      if (elColumn.width) {
        agColumn.width = parseInt(elColumn.width) || 100
        agColumn.minWidth = parseInt(elColumn.width) || 100
      }
      if (elColumn.issearch !== '0') {
        agColumn.filter = 'agTextColumnFilter'
        agColumn.floatingFilterComponent = 'TableFilter'
        agColumn.floatingFilterComponentParams = {
          props: elColumn
        }
        if (['2', '3'].includes(agColumn.issearch)) {
          this.getOptions(agColumn)
        }
        agColumn.cellRenderer = params => {
          return params.value
        }
      }
      if (agColumn.type == 10401) {
        agColumn.cellStyle = { 'text-align': 'right' }
      }
      if (agColumn.field == 'index' || agColumn.field == 'selection') {
        agColumn.cellClass = 'tms-cell-index-select'
      } else {
        agColumn.cellClass = this.cellClass
      }
      return agColumn
    },
    //获取表格下拉数据
    getOptions(column) {
      let searchData = column.searchData
      if (searchData) {
        if (searchData.startsWith('[')) {
          try {
            const options = JSON.parse(searchData)
            for (let i = 0; i < this.columns.length; i++) {
              const colDef = this.columns[i]
              if (colDef.code == column.code) {
                colDef.cellRenderer = params => {
                  return (
                    options.find(opt => opt.code == params.value).description ||
                    params.value
                  )
                }
                colDef.options = options
                bus.$emit('filterParamChange', colDef)
                break
              }
            }
            this.gridObj.api.setColumnDefs(this.columns)
          } catch (error) {
            const name = column.name || column.label
            console.log(`列表${name}字段查询数据配置有误`)
          }
        } else if (searchData.startsWith('/')) {
          this.$get(searchData).then(res => {
            const options = Array.isArray(res) ? res : res.list
            for (let i = 0; i < this.columns.length; i++) {
              const colDef = this.columns[i]
              if (colDef.code == column.code) {
                colDef.cellRenderer = params => {
                  return (
                    options.find(opt => opt.code == params.value)
                      ?.description || params.value
                  )
                }
                colDef.options = options
                bus.$emit('filterParamChange', colDef)
                break
              }
            }
            this.gridObj.api.setColumnDefs(this.columns)
          })
        } else {
          const name = column.name
          console.log(`列表${name}字段查询数据配置有误2`)
        }
      } else {
        const name = column.name
        console.log(`请配置列表${name}字段查询数据`)
      }
    },
    /**
     * ag-grid列配置项转换为el-table列配置项
     * 参数：ag-grid的列配置
     * 返回：elColumn：el-table的列配置
     */
    agGridToElTable(agColumn) {
      let elColumn = this._.cloneDeep(agColumn)
      if (elColumn.field === 'index' || elColumn.field === 'selection') {
        elColumn.type = elColumn.field
      }
      elColumn.property = elColumn.field
      elColumn.label = elColumn.headerName
      if (elColumn.filter == 'agDateColumnFilter') {
        elColumn.tmsFilterType = 'date'
      } else if (elColumn.filter == 'agNumberColumnFilter') {
        elColumn.tmsFilterType = 'number'
      } else {
        elColumn.tmsFilterType = 'string'
      }
      if (elColumn.children && !this.isResultEmpty(elColumn.children)) {
        elColumn.children = elColumn.children.map(obj => {
          return this.agGridToElTable(obj)
        })
      }
      return elColumn
    },
    rowClass(params) {
      let obj = {
        row: params.data,
        rowIndex: params.rowIndex
      }
      if (typeof this.rowClassName === 'string') {
        return this.rowClassName
      } else if (typeof this.rowClassName === 'function') {
        if (params.data.tmsSummary) {
          return ''
        } else {
          return this.rowClassName.call(null, obj)
        }
      } else {
        return ''
      }
    },
    //每页条数change
    handleSizeChange(size) {
      this.pageSize = size
      this.page = 1
      this.$emit('getTableData', size)
    },
    //当前页数change
    handleCurrentChange(currentPage) {
      this.page = currentPage
      this.getTableData()
      this.$emit('getTableData', currentPage)
    },
    //当用户手动勾选数据行的 Checkbox 时触发的事件
    select(event) {
      let selection = event.api.getSelectedRows()
      this.$emit('select', selection, event.data)
      if (!this.hasCheck) {
        this.currentChange(event)
      }
    },
    //当选择项发生变化时会触发该事件
    selectionChange(event) {
      let selection = event.api.getSelectedRows()
      this.$emit('selectData', selection)
    },
    //用于多选表格，清空用户的选择
    clearSelection() {
      this.gridObj.api && this.gridObj.api.deselectAll()
    },
    // 用于单选表格，设定某一行为选中行，如果调用时不加参数，则会取消目前高亮行的选中状态
    setCurrentRow(row) {
      this.clearSelection()
      let _self = this
      if (!_self.hasCheck) {
        _self.gridObj.api.forEachNode(function(node) {
          if (_self.isObjEqual(node.data, row)) {
            node.setSelected(true)
          }
        })
      }
    },
    //index序号格式化
    indexFormat(params) {
      console.log(params);
        if (this.pageDetail) {
          return (this.page - 1) * this.pageSize + (params.rowIndex + 1)
        } else {
          return params.rowIndex + 1
        }
    },
    onGridReady(params) {
      this.gridObj = params
      this.$emit('grid-ready', params)
    },
    onCellClicked(event) {
      if (
        event.colDef.editable === true ||
        this.defaultColDef.editable === true
      ) {
        return
      }
      if (event.colDef.field == 'edit') {
        // 这里一定是点击的编辑
        this.$emit('setdialog', event.data)
        return
      }
      // 非空则复制到粘贴板
      if (event.event.target.innerText !== '') {
        this.$copyText(event.event.target.innerText)
      }
      this.$emit('cellClick', event)
    },
    filterChangeHandler(filter) {
      this.filterParams[filter.key] = filter.filter
      this.$emit('searhData', this.page, this.filterParams)
    },
    //删除查询条件
    delSearchData() {
      // this.gridObj.api.setFilterModel(null);
      bus.$emit('resetFliterParams')
      this.page = 1
      this.filterParams = {}
      this.getTableData()
    }
  },
  watch: {
    tableConfig(val) {
      this.$emit('update:tableConfig', val)
      this.initSetting()
    },
    extraColumns(val) {
      this.$emit('update:extraColumns', val)
      this.initSetting()
    },
    columns(val) {
      this.$emit('update:columns', val)
      this.showColumns = Object.assign([], val).filter(obj => {
        return (
          obj.field !== 'index' &&
          obj.field !== 'selection' &&
          obj.field !== 'edit'
        )
      })
    },
    data(val) {
      this.getTableData()
    },
    hasCheck(val) {
      if (!val) {
        this.rowSelection = 'single'
      }
    },
  }
}
</script>
<style lang="scss" scoped>
.query-date-wrap {
  position: absolute;
  right: 0;
  top: -26px;
  span {
    display: inline-block;
    margin-right: 0;
    text-align: right;
    font-size: 14px;
  }
  .el-checkbox-group {
    display: inline-block;
  }
}
.tms-ag-grid {
  position: relative;

  &.no-edit.no-check {
  }

  .table-setting {
    position: absolute;
    top: 16px;
    z-index: 100;
    .el-icon-setting {
      font-size: 18px;
    }
  }

  .search_btn {
    position: absolute;
    top: 45px;
    z-index: 100;
    width: 42px;
    display: flex;
    justify-content: space-between;
    i {
      font-size: 18px;
    }
  }
}
</style>
